using BanZuiCloudControlAgent.Extensions.QQ;
using BanZuiCloudControlAgent.Utils.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace BanZuiCloudControlAgent.Core.QQ
{
    /// <summary>
    /// QQ管理器类，负责管理多个QQ实例
    /// </summary>
    public class QQManager : IDisposable
    {
        private readonly Dictionary<int, QQ> _qqInstances = new Dictionary<int, QQ>();
        private readonly object _lockObj = new object();
        private readonly Logger _logger = LogManager.GetLogger(nameof(QQManager));
        private Timer _cleanupTimer;
        private bool _isDisposed;

        // 单例实例
        private static QQManager _instance;
        private static readonly object _instanceLock = new object();

        /// <summary>
        /// 获取QQManager单例实例
        /// </summary>
        /// <returns>QQManager实例</returns>
        public static QQManager GetInstance()
        {
            if (_instance == null)
            {
                lock (_instanceLock)
                {
                    if (_instance == null)
                    {
                        _instance = new QQManager();
                    }
                }
            }
            return _instance;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public QQManager()
        {
            _logger.Info("QQ管理器已创建");
            // 创建定时器，定期清理不存在的QQ进程
            _cleanupTimer = new Timer(CleanupCallback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
        }

        /// <summary>
        /// 获取或创建QQ实例
        /// </summary>
        /// <param name="processId">QQ进程ID</param>
        /// <returns>QQ实例</returns>
        public QQ GetQQ(int processId)
        {
            lock (_lockObj)
            {
                if (_qqInstances.TryGetValue(processId, out QQ qq))
                {
                    return qq;
                }

                try
                {
                    qq = new QQ(processId);
                    _qqInstances.Add(processId, qq);
                    return qq;
                }
                catch (Exception ex)
                {
                    _logger.Error($"获取QQ实例失败，进程ID：{processId}，错误：{ex.Message}");
                    return null;
                }
            }
        }

        /// <summary>
        /// 获取所有QQ进程ID
        /// </summary>
        /// <returns>QQ进程ID列表</returns>
        public List<int> GetAllQQProcessIds()
        {
            try
            {
                List<int> processIds = new List<int>();
                foreach (Process process in Process.GetProcessesByName(QQConstants.ProcessName))
                {
                    processIds.Add(process.Id);
                }
                return processIds;
            }
            catch (Exception ex)
            {
                _logger.Error($"获取所有QQ进程ID失败：{ex.Message}");
                return new List<int>();
            }
        }

        /// <summary>
        /// 获取所有QQ实例
        /// </summary>
        /// <returns>QQ实例列表</returns>
        public List<QQ> GetAllQQs()
        {
            List<QQ> qqs = new List<QQ>();
            List<int> processIds = GetAllQQProcessIds();
            
            foreach (int processId in processIds)
            {
                QQ qq = GetQQ(processId);
                if (qq != null)
                {
                    qqs.Add(qq);
                }
            }
            
            return qqs;
        }

        /// <summary>
        /// 获取所有在线QQ实例
        /// </summary>
        /// <returns>在线QQ实例列表</returns>
        public List<QQ> GetOnlineQQs()
        {
            List<QQ> onlineQQs = new List<QQ>();
            List<QQ> allQQs = GetAllQQs();
            
            foreach (QQ qq in allQQs)
            {
                qq.RefreshStatus();
                if (qq.IsOnline)
                {
                    onlineQQs.Add(qq);
                }
            }
            
            return onlineQQs;
        }

        /// <summary>
        /// 刷新所有QQ实例的状态
        /// </summary>
        public void RefreshAllStatus()
        {
            lock (_lockObj)
            {
                foreach (QQ qq in _qqInstances.Values)
                {
                    try
                    {
                        qq.RefreshStatus();
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"刷新QQ状态失败，进程ID：{qq.ProcessId}，错误：{ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 清理不存在的QQ进程
        /// </summary>
        public void Cleanup()
        {
            lock (_lockObj)
            {
                List<int> existingProcessIds = GetAllQQProcessIds();
                List<int> toRemove = new List<int>();
                
                foreach (int processId in _qqInstances.Keys)
                {
                    if (!existingProcessIds.Contains(processId))
                    {
                        toRemove.Add(processId);
                    }
                }
                
                foreach (int processId in toRemove)
                {
                    try
                    {
                        _qqInstances[processId].Dispose();
                        _qqInstances.Remove(processId);
                        _logger.Info($"已清理不存在的QQ实例，进程ID：{processId}");
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"清理QQ实例失败，进程ID：{processId}，错误：{ex.Message}");
                    }
                }
                
                _logger.Info($"清理完成，当前管理的QQ实例数：{_qqInstances.Count}");
            }
        }

        /// <summary>
        /// 定时清理回调
        /// </summary>
        /// <param name="state">状态对象</param>
        private void CleanupCallback(object state)
        {
            try
            {
                Cleanup();
            }
            catch (Exception ex)
            {
                _logger.Error($"定时清理QQ实例失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 获取QQ状态摘要信息
        /// </summary>
        /// <returns>QQ状态摘要信息</returns>
        public string GetQQStatusSummary()
        {
            List<QQ> allQQs = GetAllQQs();
            int totalCount = allQQs.Count;
            int onlineCount = allQQs.Count(q => q.IsOnline);
            
            return $"QQ总数：{totalCount}，在线QQ数：{onlineCount}";
        }

        /// <summary>
        /// 获取详细的QQ信息列表
        /// </summary>
        /// <returns>详细的QQ信息列表</returns>
        public List<string> GetDetailedQQInfos()
        {
            List<string> infoList = new List<string>();
            List<QQ> allQQs = GetAllQQs();
            
            foreach (QQ qq in allQQs)
            {
                infoList.Add(qq.GetQQInfo());
            }
            
            return infoList;
        }

        /// <summary>
        /// 异步监控QQ进程变化，当有新QQ进程启动或退出时执行指定的回调
        /// </summary>
        /// <param name="newQQCallback">新QQ进程启动的回调</param>
        /// <param name="exitQQCallback">QQ进程退出的回调</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>异步任务</returns>
        public async Task MonitorQQProcessesAsync(
            Action<int> newQQCallback, 
            Action<int> exitQQCallback, 
            CancellationToken cancellationToken)
        {
            HashSet<int> knownProcessIds = new HashSet<int>(GetAllQQProcessIds());
            
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // 获取当前所有QQ进程ID
                    List<int> currentProcessIds = GetAllQQProcessIds();
                    HashSet<int> currentSet = new HashSet<int>(currentProcessIds);
                    
                    // 检测新增的进程
                    foreach (int processId in currentProcessIds)
                    {
                        if (!knownProcessIds.Contains(processId))
                        {
                            _logger.Info($"检测到新的QQ进程，ID：{processId}");
                            
                            // 执行回调
                            try
                            {
                                newQQCallback?.Invoke(processId);
                            }
                            catch (Exception ex)
                            {
                                _logger.Error($"执行新QQ进程回调失败，进程ID：{processId}，错误：{ex.Message}");
                            }
                        }
                    }
                    
                    // 检测退出的进程
                    foreach (int processId in knownProcessIds)
                    {
                        if (!currentSet.Contains(processId))
                        {
                            _logger.Info($"检测到QQ进程退出，ID：{processId}");
                            
                            // 执行回调
                            try
                            {
                                exitQQCallback?.Invoke(processId);
                            }
                            catch (Exception ex)
                            {
                                _logger.Error($"执行QQ进程退出回调失败，进程ID：{processId}，错误：{ex.Message}");
                            }
                            
                            // 从QQ管理器中移除
                            lock (_lockObj)
                            {
                                if (_qqInstances.TryGetValue(processId, out QQ qq))
                                {
                                    qq.Dispose();
                                    _qqInstances.Remove(processId);
                                    _logger.Info($"已从管理器移除退出的QQ进程，ID：{processId}");
                                }
                            }
                        }
                    }
                    
                    // 更新已知进程ID列表
                    knownProcessIds = currentSet;
                }
                catch (Exception ex)
                {
                    _logger.Error($"监控QQ进程变化失败：{ex.Message}");
                }
                
                // 等待一段时间后继续监控
                await Task.Delay(TimeSpan.FromSeconds(3), cancellationToken);
            }
        }
        
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        
        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="disposing">是否正在释放托管资源</param>
        protected virtual void Dispose(bool disposing)
        {
            if (_isDisposed)
                return;
            
            if (disposing)
            {
                lock (_lockObj)
                {
                    foreach (QQ qq in _qqInstances.Values)
                    {
                        try
                        {
                            qq.Dispose();
                        }
                        catch (Exception ex)
                        {
                            _logger.Error($"释放QQ实例资源失败，进程ID：{qq.ProcessId}，错误：{ex.Message}");
                        }
                    }
                    
                    _qqInstances.Clear();
                }
                
                _cleanupTimer?.Dispose();
                _cleanupTimer = null;
                
                // 如果是单例实例，则置空
                lock (_instanceLock)
                {
                    if (_instance == this)
                    {
                        _instance = null;
                    }
                }
                
                _logger.Info("QQ管理器已释放资源");
            }
            
            _isDisposed = true;
        }
    }
} 